<?php

/**
 * Suppport for PLUpload. The uploaded file will write to $_SESSION['pluploaded_file']
 *
 * @author LeDat
 */

Yii::import('ext.wideImage.WideImage');

class PlUploadImage extends CAction {

    public $file_name;
    public $params;
    public $session;
    public $errors;
    
    public function run() {
        $this->init();
        
        $response = array(
            'status'  => 400, //bad request = fail
            'message' => '',
            'file'    => '',
            'thumb'   => '',
        );
        
        $filePath = $this->_upload_file($this->file_name);
        if ($filePath) {
            list($response['file'], $response['thumb']) = $this->_processImage($filePath);
            
            //write to $_SESSION['pluploaded_file']
//            $this->_deleteOldFile();
            Yii::app()->user->setState('pluploaded_file', array(
                'file_name'  => $response['file'],
                'thumb_name' => $response['thumb'],
            ));
            
            $response['status'] = 200;
            $response['message'] = 'success';
        } else {
            $response['message'] = $this->errors;
        }
        
        echo json_encode($response);
    }

    public function init() {
        $this->params['upload_dir'] = Yii::app()->params['tempo_dir'];
        if (Yii::app()->user->hasState('pluploaded_file')) {
            $this->session = Yii::app()->user->getState('pluploaded_file');
        }
    }
    
    /**
     * @param string $file_name
     * @return string Return uploaded file path if success
     */
    private function _upload_file($file_name) {
        $result = null;
        
        if (isset($_FILES[$file_name])) {
            $fileObj = CUploadedFile::getInstanceByName($file_name);
            $dir = $this->params['upload_dir'];
            
            if ($this->validateFileSize($fileObj)
                && $this->validateFileExt($fileObj)
                && $this->validateDimension($fileObj)
            ) {
                if (empty($this->session)) {
                    $filePath = $dir . $this->params['basename']
                        . '_' . date('Y_m_d_H_i_s')
                        . '.' . $fileObj->getExtensionName();
                } else {
                    $filePath = $dir . $this->session['file_name'];
                    unlink($filePath); //delete old file
                }
                
                if (is_dir($this->params['upload_dir']) && $fileObj->saveAs($filePath)) {
                    $result = $filePath;
                } else {
                    $this->errors = $this->params['upload_dir']
                        . ' or ' . $filePath
                        . ' does not exits.';
                }
            }
        } else {
            $this->errors = "\$_FILES[$file_name] does not exist";
        }
        
        return $result;
    }
    
    /**
     * @param CUploadedFile $file
     * @return boolean
     */
    protected function validateFileExt($file) {
        $aValid = array('jpg', 'png', 'gif');
        if (in_array($file->getExtensionName(), $aValid)) {
            return TRUE;
        } else {
            $this->errors = 'Please upload file: *.jpg, *.png, *.gif';
            return FALSE;
        }
    }
    
    /**
     * @param CUploadedFile $file
     * @return boolean
     */
    protected function validateFileSize($file) {
        $maxSize = (int) $this->params['max_size'];
        $fileSize = $file->getSize() / (1024*1024); //convert byte to mega byte
        
        if ($fileSize <= $maxSize) {
            return TRUE;
        } else {
            $this->errors = 'Please upload file size < ' . $this->params['max_size'] . 'MB';
            return FALSE;
        }
    }

    /**
     * @param CUploadedFile $file
     * @return boolean
     */
    protected function validateDimension($file) {
        $path = $file->tempName;
        $obj = WideImage::load($path);

        if ( (! empty($this->params['width'])) && (! empty($this->params['height'])) ) {
            if ( $obj->getWidth() == $this->params['width'] 
              && $obj->getHeight() == $this->params['height']
            ) {
                return TRUE;
            } else {
                $this->errors = 'Please upload image in dimension: '
                    . $this->params['width'] . ' x '
                    . $this->params['height'] . ' pixels';
                return FALSE;
            }
        } elseif ( (empty($this->params['width'])) || (empty($this->params['height'])) ) {
            if ( (empty($this->params['width'])) && (empty($this->params['height'])) ) {
                return TRUE;
            } elseif ( (empty($this->params['width'])) && ($obj->getHeight() != $this->params['height']) ) {
                $this->errors = 'Please upload image with '
                    . $this->params['height'] . ' pixels in Height';
                return FALSE;
            } elseif ( (empty($this->params['height'])) && ($obj->getWidth() != $this->params['width']) ) {
                $this->errors = 'Please upload image with '
                    . $this->params['width'] . ' pixels in Width';
                return FALSE;
            } else {
                return TRUE;
            }
        }
        
    }
    
    private function _processImage($filePath) {
        //thumb path
        $fileInfo = pathinfo($filePath);
        $thumbName = $fileInfo['filename'] . '_thumb.' . $fileInfo['extension'];
        $thumbPath = $fileInfo['dirname'] . '/' . $thumbName;
        
        //resize
        $fileObj = WideImage::load($filePath);
        $fileObj->resizeDown($this->params['thumb_width'], $this->params['thumb_height'])
            ->saveToFile($thumbPath);
        
        //create thumbnail
        $thumbObj = WideImage::load($thumbPath);
        $bg = $thumbObj->allocateColor(
            $this->params['thumb_bg']['0'],
            $this->params['thumb_bg']['1'],
            $this->params['thumb_bg']['2']
        );
        $thumbObj->resizeCanvas($this->params['thumb_width'], $this->params['thumb_height'],
            'center', 'center', $bg)
            ->saveToFile($thumbPath);
        
        return array(
            $fileInfo['basename'],
            $thumbName
        );
    }
    
}